package com.yanmaohu.yulia.token;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Bright Lee
 */
public enum TokenType {

    EOF(null, false, false),
    REGULAR_IDENTIFIER(null, false, false),
    UNICODE_DELIMITER_BODY(null, false, false),

    UNSIGNED_INTEGER_LITERAL(null, false, false),
    STRING_LITERAL(null, false, false),

    DOUBLE_QUOTE("\"", false, true),
    PERCENT("%", false, true),
    AMPERSAND("&", false, true),
    QUOTE("'", false, true),
    LEFT_PAREN("(", false, true),
    RIGHT_PAREN(")", false, true),
    ASTERISK("*", false, true),
    PLUS_SIGN("+", false, true),
    COMMA(",", false, true),
    MINUS_SIGN("-", false, true),
    PERIOD(".", false, true),
    SOLIDUS("/", false, true),
    COLON(":", false, true),
    SEMICOLON(";", false, true),
    LESS_THAN_OPERATOR("<", false, true),
    LESS_THAN_OR_EQUALS_OPERATOR("<=", false, true),
    NOT_EQUALS_OPERATOR("<>", false, true),
    EQUALS_OPERATOR("=", false, true),
    GREATER_THAN_OPERATOR(">", false, true),
    GREATER_THAN_OR_EQUALS_OPERATOR(">=", false, true),
    QUESTION_MARK("?", false, true),
    LEFT_BRACKET("[", false, true),
    LEFT_BRACKET_TRIGRAPH("??(", false, true),
    RIGHT_BRACKET("]", false, true),
    RIGHT_BRACKET_TRIGRAPH("??)", false, true),
    CIRCUMFLEX("^", false, true),
    UNDERSCORE("_", false, true),
    VERTICAL_BAR("|", false, true),
    CONCATENATION_OPERATOR("||", false, true),
    LEFT_BRACE("{", false, true),
    RIGHT_BRACE("}", false, true),

    ADD("ADD", true, false),
    ALL("ALL", true, false),
    ALLOCATE("ALLOCATE", true, false),
    ALTER("ALTER", true, false),
    AND("AND", true, false),
    ANY("ANY", true, false),
    ARE("ARE", true, false),
    ARRAY("ARRAY", true, false),
    AS("AS", true, false),
    ASENSITIVE("ASENSITIVE", true, false),
    ASYMMETRIC("ASYMMETRIC", true, false),
    AT("AT", true, false),
    ATOMIC("ATOMIC", true, false),
    AUTHORIZATION("AUTHORIZATION", true, false),
    BEGIN("BEGIN", true, false),
    BETWEEN("BETWEEN", true, false),
    BIGINT("BIGINT", true, false),
    BINARY("BINARY", true, false),
    BLOB("BLOB", true, false),
    BOOLEAN("BOOLEAN", true, false),
    BOTH("BOTH", true, false),
    BY("BY", true, false),
    CALL("CALL", true, false),
    CALLED("CALLED", true, false),
    CASCADED("CASCADED", true, false),
    CASE("CASE", true, false),
    CAST("CAST", true, false),
    CHAR("CHAR", true, false),
    CHARACTER("CHARACTER", true, false),
    CHECK("CHECK", true, false),
    CLOB("CLOB", true, false),
    CLOSE("CLOSE", true, false),
    COLLATE("COLLATE", true, false),
    COLUMN("COLUMN", true, false),
    COMMIT("COMMIT", true, false),
    CONNECT("CONNECT", true, false),
    CONSTRAINT("CONSTRAINT", true, false),
    CONTINUE("CONTINUE", true, false),
    CORRESPONDING("CORRESPONDING", true, false),
    CREATE("CREATE", true, false),
    CROSS("CROSS", true, false),
    CUBE("CUBE", true, false),
    CURRENT("CURRENT", true, false),
    CURRENT_DATE("CURRENT_DATE", true, false),
    CURRENT_DEFAULT_TRANSFORM_GROUP("CURRENT_DEFAULT_TRANSFORM_GROUP", true, false),
    CURRENT_PATH("CURRENT_PATH", true, false),
    CURRENT_ROLE("CURRENT_ROLE", true, false),
    CURRENT_TIME("CURRENT_TIME", true, false),
    CURRENT_TIMESTAMP("CURRENT_TIMESTAMP", true, false),
    CURRENT_TRANSFORM_GROUP_FOR_TYPE("CURRENT_TRANSFORM_GROUP_FOR_TYPE", true, false),
    CURRENT_USER("CURRENT_USER", true, false),
    CURSOR("CURSOR", true, false),
    CYCLE("CYCLE", true, false),
    DATE("DATE", true, false),
    DAY("DAY", true, false),
    DEALLOCATE("DEALLOCATE", true, false),
    DEC("DEC", true, false),
    DECIMAL("DECIMAL", true, false),
    DECLARE("DECLARE", true, false),
    DEFAULT("DEFAULT", true, false),
    DELETE("DELETE", true, false),
    DEREF("DEREF", true, false),
    DESCRIBE("DESCRIBE", true, false),
    DETERMINISTIC("DETERMINISTIC", true, false),
    DISCONNECT("DISCONNECT", true, false),
    DISTINCT("DISTINCT", true, false),
    DOUBLE("DOUBLE", true, false),
    DROP("DROP", true, false),
    DYNAMIC("DYNAMIC", true, false),
    EACH("EACH", true, false),
    ELEMENT("ELEMENT", true, false),
    ELSE("ELSE", true, false),
    END("END", true, false),
    END_EXEC("END -EXEC", true, false),
    ESCAPE("ESCAPE", true, false),
    EXCEPT("EXCEPT", true, false),
    EXEC("EXEC", true, false),
    EXECUTE("EXECUTE", true, false),
    EXISTS("EXISTS", true, false),
    EXTERNAL("EXTERNAL", true, false),
    FALSE("FALSE", true, false),
    FETCH("FETCH", true, false),
    FILTER("FILTER", true, false),
    FLOAT("FLOAT", true, false),
    FOR("FOR", true, false),
    FOREIGN("FOREIGN", true, false),
    FREE("FREE", true, false),
    FROM("FROM", true, false),
    FULL("FULL", true, false),
    FUNCTION("FUNCTION", true, false),
    GET("GET", true, false),
    GLOBAL("GLOBAL", true, false),
    GRANT("GRANT", true, false),
    GROUP("GROUP", true, false),
    GROUPING("GROUPING", true, false),
    HAVING("HAVING", true, false),
    HOLD("HOLD", true, false),
    HOUR("HOUR", true, false),
    IDENTITY("IDENTITY", true, false),
    IMMEDIATE("IMMEDIATE", true, false),
    IN("IN", true, false),
    INDICATOR("INDICATOR", true, false),
    INNER("INNER", true, false),
    INOUT("INOUT", true, false),
    INPUT("INPUT", true, false),
    INSENSITIVE("INSENSITIVE", true, false),
    INSERT("INSERT", true, false),
    INT("INT", true, false),
    INTEGER("INTEGER", true, false),
    INTERSECT("INTERSECT", true, false),
    INTERVAL("INTERVAL", true, false),
    INTO("INTO", true, false),
    IS("IS", true, false),
    ISOLATION("ISOLATION", true, false),
    JOIN("JOIN", true, false),
    LANGUAGE("LANGUAGE", true, false),
    LARGE("LARGE", true, false),
    LATERAL("LATERAL", true, false),
    LEADING("LEADING", true, false),
    LEFT("LEFT", true, false),
    LIKE("LIKE", true, false),
    LOCAL("LOCAL", true, false),
    LOCALTIME("LOCALTIME", true, false),
    LOCALTIMESTAMP("LOCALTIMESTAMP", true, false),
    MATCH("MATCH", true, false),
    MEMBER("MEMBER", true, false),
    MERGE("MERGE", true, false),
    METHOD("METHOD", true, false),
    MINUTE("MINUTE", true, false),
    MODIFIES("MODIFIES", true, false),
    MODULE("MODULE", true, false),
    MONTH("MONTH", true, false),
    MULTISET("MULTISET", true, false),
    NATIONAL("NATIONAL", true, false),
    NATURAL("NATURAL", true, false),
    NCHAR("NCHAR", true, false),
    NCLOB("NCLOB", true, false),
    NEW("NEW", true, false),
    NO("NO", true, false),
    NONE("NONE", true, false),
    NOT("NOT", true, false),
    NULL("NULL", true, false),
    NUMERIC("NUMERIC", true, false),
    OF("OF", true, false),
    OLD("OLD", true, false),
    ON("ON", true, false),
    ONLY("ONLY", true, false),
    OPEN("OPEN", true, false),
    OR("OR", true, false),
    ORDER("ORDER", true, false),
    OUT("OUT", true, false),
    OUTER("OUTER", true, false),
    OUTPUT("OUTPUT", true, false),
    OVER("OVER", true, false),
    OVERLAPS("OVERLAPS", true, false),
    PARAMETER("PARAMETER", true, false),
    PARTITION("PARTITION", true, false),
    PRECISION("PRECISION", true, false),
    PREPARE("PREPARE", true, false),
    PRIMARY("PRIMARY", true, false),
    PROCEDURE("PROCEDURE", true, false),
    RANGE("RANGE", true, false),
    READS("READS", true, false),
    REAL("REAL", true, false),
    RECURSIVE("RECURSIVE", true, false),
    REF("REF", true, false),
    REFERENCES("REFERENCES", true, false),
    REFERENCING("REFERENCING", true, false),
    RELEASE("RELEASE", true, false),
    RETURN("RETURN", true, false),
    RETURNS("RETURNS", true, false),
    REVOKE("REVOKE", true, false),
    RIGHT("RIGHT", true, false),
    ROLLBACK("ROLLBACK", true, false),
    ROLLUP("ROLLUP", true, false),
    ROW("ROW", true, false),
    ROWS("ROWS", true, false),
    SAVEPOINT("SAVEPOINT", true, false),
    SCROLL("SCROLL", true, false),
    SEARCH("SEARCH", true, false),
    SECOND("SECOND", true, false),
    SELECT("SELECT", true, false),
    SENSITIVE("SENSITIVE", true, false),
    SESSION_USER("SESSION_USER", true, false),
    SET("SET", true, false),
    SIMILAR("SIMILAR", true, false),
    SMALLINT("SMALLINT", true, false),
    SOME("SOME", true, false),
    SPECIFIC("SPECIFIC", true, false),
    SPECIFICTYPE("SPECIFICTYPE", true, false),
    SQL("SQL", true, false),
    SQLEXCEPTION("SQLEXCEPTION", true, false),
    SQLSTATE("SQLSTATE", true, false),
    SQLWARNING("SQLWARNING", true, false),
    START("START", true, false),
    STATIC("STATIC", true, false),
    SUBMULTISET("SUBMULTISET", true, false),
    SYMMETRIC("SYMMETRIC", true, false),
    SYSTEM("SYSTEM", true, false),
    SYSTEM_USER("SYSTEM_USER", true, false),
    TABLE("TABLE", true, false),
    THEN("THEN", true, false),
    TIME("TIME", true, false),
    TIMESTAMP("TIMESTAMP", true, false),
    TIMEZONE_HOUR("TIMEZONE_HOUR", true, false),
    TIMEZONE_MINUTE("TIMEZONE_MINUTE", true, false),
    TO("TO", true, false),
    TRAILING("TRAILING", true, false),
    TRANSLATION("TRANSLATION", true, false),
    TREAT("TREAT", true, false),
    TRIGGER("TRIGGER", true, false),
    TRUE("TRUE", true, false),
    UNION("UNION", true, false),
    UNIQUE("UNIQUE", true, false),
    UNKNOWN("UNKNOWN", true, false),
    UNNEST("UNNEST", true, false),
    UPDATE("UPDATE", true, false),
    USER("USER", true, false),
    USING("USING", true, false),
    VALUE("VALUE", true, false),
    VALUES("VALUES", true, false),
    VARCHAR("VARCHAR", true, false),
    VARYING("VARYING", true, false),
    WHEN("WHEN", true, false),
    WHENEVER("WHENEVER", true, false),
    WHERE("WHERE", true, false),
    WINDOW("WINDOW", true, false),
    WITH("WITH", true, false),
    WITHIN("WITHIN", true, false),
    WITHOUT("WITHOUT", true, false),
    YEAR("YEAR", true, false);

    private static final Map<String, TokenType> RESERVED_WORD_MAP = new HashMap<>();
    static {
        for (TokenType tokenType : values()) {
            if (!tokenType.isReservedWord()) {
                continue;
            }
            RESERVED_WORD_MAP.put(tokenType.getContent(), tokenType);
        }
    }
    public static TokenType getReservedWordTokenType(String content) {
        if (content == null || content.isEmpty()) {
            return null;
        }
        return RESERVED_WORD_MAP.get(content.toUpperCase());
    }

    private final String content;
    private final boolean reservedWord;
    private final boolean operator;

    TokenType(String content, boolean reservedWord, boolean operator) {
        this.content = content;
        this.reservedWord = reservedWord;
        this.operator = operator;
    }

    public String getContent() {
        return content;
    }

    public boolean isReservedWord() {
        return reservedWord;
    }

    public boolean isOperator() {
        return operator;
    }

}
